//Copyright (C) 2007 James Ashley (www.imaginativeuniversal.com) under the terms of the LGPL.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;

namespace SophiaBot
{
    abstract public class BotServerBase: IBotServer
    {
        #region local fields

        protected bool _isRunning = false;
        protected string _name = "Bot Server Base Class";
        protected int _priority = 125;
        protected IBotServer _nextBot = null;
        protected static object staticLock = new object();

        #endregion

        #region IBotServer Members

        public event GenericEventHandler<IBotServer, string> OnBotInfoResponse;
        public event GenericEventHandler<IBotServer, string> OnBotResponse;
        public event GenericEventHandler<string> OnUserInput;
        public event GenericEventHandler<string> OnTextRecognized;
        public event EventHandler<FinishEventArgs> OnFinish;
        public event EventHandler OnStart;

        protected void RaiseBotInfoResponseEvent(IBotServer bot, string val)
        {
            if (null != OnBotInfoResponse)
                OnBotInfoResponse(bot, val);
        }

        protected void RaiseBotResponseEvent(IBotServer bot, string val)
        {
            if (null != OnBotResponse)
                OnBotResponse(bot, val);
        }

        protected void RaiseUserInputEvent(string val)
        {
            if (null != OnUserInput)
                OnUserInput(val);
        }

        protected void RaiseTextRecognizedEvent(string val)
        {
            if (null != OnTextRecognized)
                OnTextRecognized(val);
        }

        protected void RaiseOnFinishEvent(object source, FinishEventArgs e)
        {
            if (null != OnFinish)
                OnFinish(source, e);
        }

        protected void RaiseOnStartEvent(object source, EventArgs e)
        {
            if (null != OnStart)
                OnStart(source, e);
        }

        /// <summary>
        /// Gets a value indicating whether this instance is running.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is running; otherwise, <c>false</c>.
        /// </value>
        public bool IsRunning
        {
            get { return _isRunning; }
        }

        /// <summary>
        /// Gets the name.
        /// </summary>
        /// <value>The name.</value>
        public string Name
        {
            get { return _name; }
        }

        /// <summary>
        /// Sets the priority.
        /// </summary>
        /// <value>The priority.</value>
        public int Priority
        {
            set
            {
                _priority = value;
                if (null != _nextBot)
                    _nextBot.Priority = this._priority - 1;
            }
        }

        /// <summary>
        /// Adds the next bot.
        /// </summary>
        /// <param name="bot">The bot.</param>
        public void AddNextBot(IBotServer bot)
        {
            if (_nextBot != null)
            {
                //push to the end
                _nextBot.AddNextBot(bot);
            }
            else
            {
                _nextBot = bot;
                bot.Priority = this._priority - 1;
            }
        }

        /// <summary>
        /// Starts this instance.
        /// </summary>
        virtual public void Start()
        {
            _isRunning = true;
            if (null != OnStart)
                OnStart(this, EventArgs.Empty);
        }

        /// <summary>
        /// Stops this instance.
        /// </summary>
        virtual public void Stop()
        {
            _isRunning = false;
            if (null != OnFinish)
                OnFinish(this, FinishEventArgs.Empty);
        }

        virtual public string GetStatus()
        {
            if (_isRunning)
                return "...waiting";
            else
                return "...stopped";
        }

        abstract public void Read(string inputText);
        abstract public System.Speech.Recognition.Grammar[] GetGrammars();
        abstract public void Start(string val);

        #endregion

        #region helper methods
        /// <summary>
        /// Formats the input for display.
        /// </summary>
        /// <param name="inputText">The input text.</param>
        /// <returns></returns>
        protected virtual string FormatInputForDisplay(string inputText)
        {
            inputText = inputText.Trim();
            if (inputText.Length > 0)
            {
                //get last character
                string c = inputText.Substring(inputText.Length - 1);
                if ("abcdefghijklmnopqrstuvwxyz012345678".IndexOf(c, StringComparison.CurrentCultureIgnoreCase) > -1)
                {
                    inputText = inputText + ".";
                }
            }
            return inputText;
        }

        /// <summary>
        /// Formats input to proper case.
        /// </summary>
        /// <param name="inputText">The input text.</param>
        /// <returns></returns>
        protected virtual string FormatProperCase(string inputText)
        {
            if (inputText.Length > 0)
                inputText = inputText.Substring(0, 1).ToUpper() + inputText.Substring(1).ToLower();

            return inputText;
        }

        #endregion

        #region debug console output

        /// <summary>
        /// Write to console when in debug mode.
        /// </summary>
        /// <param name="message">The message.</param>
        [Conditional("DEBUG")]
        static public void DebugWriteToConsole(string message)
        {
            Console.WriteLine(message);
        }
        #endregion
    }
}
